package cn.xuqiudong.attachment.util;

import cn.xuqiudong.common.base.exception.CommonException;
import cn.xuqiudong.common.base.vo.BooleanWithMsg;
import cn.xuqiudong.common.util.JsonUtil;
import cn.xuqiudong.common.util.encrypt.AesUtil;
import org.apache.commons.lang3.StringUtils;

/**
 * 描述: 客户端校验， 通过AES 堆成加密，两边持有相同的加密key(长度需要为16)
 * @author Vic.xu
 * @since 2022-11-28 10:43
 */
public class ClientVerifyUtil {

    /**
     * 过期时间：5分钟之内
     */
    private static final long EXPIRE_DURATION = 5 * 60 * 1000;

    private static final int KEY_SIZE = 16;


    /**
     * 校验签名
     * @param sign sign
     * @param key key
     * @param contents 需要对比的内容（多个）
     * @return BooleanWithMsg
     */
    public static BooleanWithMsg verifySign(String sign, String key, String[] contents) {
        if (contents == null || contents.length == 0) {
            return BooleanWithMsg.success();
        }
        if (StringUtils.isBlank(sign)) {
            return BooleanWithMsg.fail("不存在签名信息");
        }
        try {
            String json = AesUtil.decrypt(sign, key);
            SignModel signModel = JsonUtil.jsonToObject(json, SignModel.class);
            if (signModel == null) {
                return BooleanWithMsg.fail("签名不合法");
            }
            if (signModel.expire()) {
                return BooleanWithMsg.fail("签名已过期");
            }
            for (String content : contents) {
                if (StringUtils.equals(signModel.getContent(), content)) {
                    return BooleanWithMsg.success();
                }
            }
            return BooleanWithMsg.fail("签名内容不合法");
        } catch (Exception e) {
            e.printStackTrace();
            return BooleanWithMsg.fail("解密失败：" + e.getMessage());
        }
    }

    /**
     * 生成签名
     * @param content 要加密的内容
     * @param key 加密key
     * @return sign
     * @throws Exception ex
     */
    public static String generateSign(String content, String key) {
        SignModel signModel = new SignModel(content);
        String json = JsonUtil.toJson(signModel);
        try {
            return AesUtil.encrypt(json, key);
        } catch (Exception e) {
            e.printStackTrace();
            throw new CommonException("生成签名失败: " + e.getMessage());
        }

    }


    public static class SignModel {
        /**
         * 创建时间的时间戳
         */
        private long timestamp;

        /**
         * 内容
         */
        private String content;

        public SignModel() {
        }

        public SignModel(String content) {
            this.content = content;
            this.timestamp = System.currentTimeMillis();
        }

        /**
         * 是否过期 需要5分钟之内
         * @return boolean
         */
        public boolean expire() {
            return timestamp + EXPIRE_DURATION < System.currentTimeMillis();
        }

        public long getTimestamp() {
            return timestamp;
        }

        public void setTimestamp(long timestamp) {
            this.timestamp = timestamp;
        }

        public String getContent() {
            return content;
        }

        public void setContent(String content) {
            this.content = content;
        }
    }
    
}
